﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;

namespace DBProvider.Providers
{
	public class VideoProvider : IVideoProvider
	{
		#region IVideoProvider Members

		public Video CreateVideo(Video theNewVideo, out string msg)
		{
			if(theNewVideo == null)
			{
				throw new ArgumentNullException();
			}

			msg = string.Empty;
			Video result = null;

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					var isExist = db.Videos.Count(v => v.VideoTitle == theNewVideo.VideoTitle) > 0;

					if(isExist)
					{
						msg = "同名的标题已存在";
					}
					else
					{
						db.Videos.InsertOnSubmit(theNewVideo);
						db.SubmitChanges();

						result = db.Videos.SingleOrDefault(v => v.VideoTitle == theNewVideo.VideoTitle);
					}
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}

			return result;
		}

		public bool UpdateVideo(Video theVideo)
		{
			if(theVideo == null || theVideo.VideoID <= 0)
			{
				throw new ArgumentException();
			}

			var result = false;

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					var dbVideo = db.Videos.SingleOrDefault(v => v.VideoID == theVideo.VideoID);

					if(dbVideo != null)
					{
						dbVideo.Clone(theVideo);
						db.SubmitChanges();

						result = true;
					}
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}

			return result;
		}

		public bool DeleteVideo(int videoID)
		{
			if(videoID <= 0)
			{
				throw new ArgumentOutOfRangeException();
			}

			var result = false;

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					var tagSubmit = false;

					var dbRltVideoAndShareTo = db.RLT_VideoAndShareTos.Where(vs => vs.VideoID == videoID);

					if(dbRltVideoAndShareTo != null)
					{
						db.RLT_VideoAndShareTos.DeleteAllOnSubmit(dbRltVideoAndShareTo);
						tagSubmit = true;
					}

					var dbVideo = db.Videos.SingleOrDefault(v => v.VideoID == videoID);

					if(dbVideo != null)
					{
						db.Videos.DeleteOnSubmit(dbVideo);

						tagSubmit = true;
					}

					if(tagSubmit)
					{
						db.SubmitChanges();

						result = true;
					}
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}

			return result;
		}

		public Video GetVideo(int videoID)
		{
			if(videoID <= 0)
			{
				throw new ArgumentOutOfRangeException();
			}

			Video result = null;

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					result = db.Videos.SingleOrDefault(v => v.VideoID == videoID);
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}

			return result;
		}

		public List<Video> GetVideoByCategory(int videoCategoryID)
		{
			if(videoCategoryID <= 0)
			{
				throw new ArgumentOutOfRangeException();
			}

			List<Video> result = null;

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					var data = db.Videos.Where(v => v.VideoCategoryID == videoCategoryID);

					if(data != null)
					{
						result = data.ToList();
					}
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}

			return result;
		}

		public List<VideoCategory> GetAllVideoCategory()
		{
			List<VideoCategory> result = null;

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					var data = db.VideoCategories;

					if(data != null)
					{
						result = data.ToList();
					}
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}

			return result;
		}

		public List<Video> GetVideoByUser(int userID)
		{
			if(userID <= 0)
			{
				throw new ArgumentOutOfRangeException();
			}

			List<Video> result = null;

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					var data = db.Videos.Where(v => v.VideoUserID == userID);

					if(data != null)
					{
						result = data.ToList();
					}
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}

			return result;
		}

		public List<Video> GetVideos(int drugStoreID)
		{
			if(drugStoreID <= 0)
			{
				throw new ArgumentException();
			}

			List<Video> result = null;

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					var data = db.Videos.Where(v => v.DrugStoreID == drugStoreID).OrderByDescending(v => v.VideoAddDate);

					if(data != null)
					{
						result = data.ToList();
					}
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}

			return result;
		}

		public List<Video> GetVideoExcludeUser(int userID, int drugStoreID)
		{
			if(userID <= 0 || drugStoreID <= 0)
			{
				throw new ArgumentOutOfRangeException();
			}

			List<Video> result = null;

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					//var data = db.Videos.Where(v => v.VideoUserID != userID && v.DrugStoreID == drugStoreID && v.IsPublic == 1).OrderByDescending(v => v.VideoAddDate);
					DataLoadOptions dlo = new DataLoadOptions();
					dlo.LoadWith<User>(q => q.Role);
					db.LoadOptions = dlo;

					var user = db.Users.SingleOrDefault(u => u.UserID == userID);

					if(user.Role.RoleName.ToLower().Equals("admin"))
					{
						var data = db.Videos.Where(v => v.VideoUserID != userID && v.DrugStoreID == drugStoreID && v.IsPublic == 1).OrderByDescending(v => v.VideoAddDate);

						if(data != null)
						{
							result = data.ToList();
						}
					}
					else
					{
						var data = from v in db.Videos
											 where (v.DrugStoreID == user.DrugStoreID) || (v.IsPublic == 1 && v.VideoUserID != userID) || ((from vs in db.RLT_VideoAndShareTos
																																																											where vs.ShareToDrugStoreID == user.DrugStoreID
																																																											select vs.VideoID).Contains(v.VideoID)) || ((from vs in db.RLT_VideoAndShareTos
																																																																																	 where vs.ShareToMemberID == userID
																																																																																	 select vs.VideoID).Contains(v.VideoID))
											 orderby v.VideoAddDate descending
											 select v;

						if(data != null)
						{
							result = data.ToList();
						}
					}
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}

			return result;
		}

		public List<Video> GetVideoByUser(int userID, int pageIndex, int pageSize, out int totalRecords)
		{
			if(userID <= 0)
			{
				throw new ArgumentOutOfRangeException();
			}

			List<Video> result = null;

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					totalRecords = db.Videos.Where(v => v.VideoUserID == userID).Count();

					var data = db.Videos.Where(v => v.VideoUserID == userID).OrderByDescending(v => v.VideoAddDate).Skip(pageIndex * pageSize).Take(pageSize);

					if(data != null)
					{
						result = data.ToList();
					}
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}

			return result;
		}

		public List<Video> GetVideos(int pageIndex, int pageSize, out int totalRecords, int drugStoreID)
		{
			if(drugStoreID <= 0)
			{
				throw new ArgumentException();
			}

			List<Video> result = null;

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					totalRecords = db.Videos.Where(v => v.DrugStoreID == drugStoreID).Count();
					var data = db.Videos.Where(v => v.DrugStoreID == drugStoreID).OrderByDescending(v => v.VideoAddDate).Skip(pageIndex * pageSize).Take(pageSize);

					if(data != null)
					{
						result = data.ToList();
					}
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}

			return result;
		}

		public List<Video> GetVideoExcludeUser(int userID, int drugStoreID, int pageIndex, int pageSize, out int totalRecords)
		{
			if(userID <= 0 || drugStoreID <= 0)
			{
				throw new ArgumentOutOfRangeException();
			}

			List<Video> result = null;

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					DataLoadOptions dlo = new DataLoadOptions();
					dlo.LoadWith<User>(q => q.Role);
					db.LoadOptions = dlo;

					var user = db.Users.SingleOrDefault(u => u.UserID == userID);

					if(user.Role.RoleName.ToLower().Equals("admin"))
					{
						totalRecords = db.Videos.Count(v => v.VideoUserID != userID && v.DrugStoreID == drugStoreID && v.IsPublic == 1);
						var data = db.Videos.Where(v => v.VideoUserID != userID && v.DrugStoreID == drugStoreID && v.IsPublic == 1).OrderByDescending(v => v.VideoAddDate).Skip(pageIndex * pageSize).Take(pageSize);

						if(data != null)
						{
							result = data.ToList();
						}
					}
					else
					{
						totalRecords = (from v in db.Videos
														where (v.DrugStoreID == user.DrugStoreID) || (v.IsPublic == 1 && v.VideoUserID != userID) || ((from vs in db.RLT_VideoAndShareTos
																																																													 where vs.ShareToDrugStoreID == user.DrugStoreID
																																																													 select vs.VideoID).Contains(v.VideoID)) || ((from vs in db.RLT_VideoAndShareTos
																																																																																				where vs.ShareToMemberID == userID
																																																																																				select vs.VideoID).Contains(v.VideoID))
														select v).Count();
						//var data = db.Videos.Where(v => v.VideoUserID != userID && v.DrugStoreID == drugStoreID && v.IsPublic == 1).OrderByDescending(v => v.VideoAddDate).Skip(pageIndex * pageSize).Take(pageSize);

						var data = (from v in db.Videos
												where (v.DrugStoreID == user.DrugStoreID) || (v.IsPublic == 1 && v.VideoUserID != userID) || ((from vs in db.RLT_VideoAndShareTos
																																																											 where vs.ShareToDrugStoreID == user.DrugStoreID
																																																											 select vs.VideoID).Contains(v.VideoID)) || ((from vs in db.RLT_VideoAndShareTos
																																																																																		where vs.ShareToMemberID == userID
																																																																																		select vs.VideoID).Contains(v.VideoID))
												orderby v.VideoAddDate descending
												select v).Skip(pageIndex * pageSize).Take(pageSize);

						if(data != null)
						{
							result = data.ToList();
						}
					}
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}

			return result;
		}

		public List<Video> GetNewVideos(int count, int drugStoreID)
		{
			if(count <= 0 || drugStoreID <= 0)
			{
				throw new ArgumentOutOfRangeException();
			}

			List<Video> result = null;

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					var data = from v in db.Videos
										 where v.DrugStoreID == drugStoreID || v.IsPublic == 1
										 orderby v.VideoAddDate descending
										 select v;

					if(data != null)
					{
						result = data.Take(count).ToList();
					}
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}

			return result;
		}

		public List<RLT_VideoAndShareTo> GetVideoAndShareToByVideo(int videoID)
		{
			if(videoID <= 0)
			{
				throw new ArgumentOutOfRangeException();
			}

			List<RLT_VideoAndShareTo> result = null;

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					DataLoadOptions dlo = new DataLoadOptions();
					dlo.LoadWith<RLT_VideoAndShareTo>(vs => vs.User);
					db.LoadOptions = dlo;

					var data = from vs in db.RLT_VideoAndShareTos
										 where vs.VideoID == videoID
										 select vs;

					if(data != null)
					{
						result = data.ToList();
					}
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}

			return result;
		}

		public void CreateVideoAndShareTo(List<RLT_VideoAndShareTo> lstVideoAndShareTo)
		{
			if(lstVideoAndShareTo == null || lstVideoAndShareTo.Count <= 0)
			{
				throw new ArgumentOutOfRangeException();
			}

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					db.RLT_VideoAndShareTos.InsertAllOnSubmit(lstVideoAndShareTo);
					db.SubmitChanges();
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}
		}

		public void SaveVideoAndShareTo(int videoID, List<RLT_VideoAndShareTo> lstVideoAndShareTo)
		{
			if(videoID <= 0 || lstVideoAndShareTo == null)
			{
				throw new ArgumentOutOfRangeException();
			}

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					var dbVideoAndShareTo = from vs in db.RLT_VideoAndShareTos
																	where vs.VideoID == videoID
																	select vs;

					if(dbVideoAndShareTo != null)
					{
						var lstDBVideoAndShareTo = dbVideoAndShareTo.ToList();

						var deleteItems = lstDBVideoAndShareTo.Except(lstVideoAndShareTo);

						if(deleteItems != null)
						{
							db.RLT_VideoAndShareTos.DeleteAllOnSubmit(deleteItems);
						}

						var newItems = lstVideoAndShareTo.Except(lstDBVideoAndShareTo);

						if(newItems != null)
						{
							db.RLT_VideoAndShareTos.InsertAllOnSubmit(newItems);
						}

						db.SubmitChanges();
					}
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}
		}

		public List<Video> GetNewVideos(int count, int drugStoreID, int userID)
		{
			if(count <= 0 || drugStoreID <= 0 || userID <= 0)
			{
				throw new ArgumentOutOfRangeException();
			}

			List<Video> result = null;

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					var user = db.Users.SingleOrDefault(u => u.UserID == userID);

					var data = from v in db.Videos
										 where (v.DrugStoreID == drugStoreID) || (v.IsPublic == 1 && v.VideoUserID != userID) || ((from vs in db.RLT_VideoAndShareTos
																																																							 where vs.ShareToDrugStoreID == user.DrugStoreID
																																																							 select vs.VideoID).Contains(v.VideoID)) || ((from vs in db.RLT_VideoAndShareTos
																																																																														where vs.ShareToMemberID == userID
																																																																														select vs.VideoID).Contains(v.VideoID))
										 orderby v.VideoAddDate descending
										 select v;

					if(data != null)
					{
						result = data.Take(count).ToList();
					}
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}

			return result;
		}

		#endregion
	}
}
